#!/usr/bin/php
<?php 
/**
 * SchoolBus BETA v 0.2
 * Dan Semaya
 * dsemaya@mac.com
 * http://semaya.net/projects
 * c. November 8, 2005
 * 
 * written using PHP, Pashua and CocoaDialog
 */
 
define("CDPATH", "CocoaDialog.app");
function CDokmsgbox($title,$text,$informtext,$nocancel=false,$style='informational')
{
    $execstr=CDPATH."/Contents/MacOS/CocoaDialog ok-msgbox --text \"$text\" --informative-text \"$informtext\" --style $style --title \"$title\" ";
    if ($nocancel) $execstr.='--no-cancel';
    return exec($execstr);
}

$workingpath = substr($_SERVER['SCRIPT_NAME'], 0, strlen($_SERVER['SCRIPT_NAME']) - strlen("SchoolBus"));
chdir($workingpath);

function pashua_run($conf) {

	// Check for safe mode
	if (ini_get('safe_mode')) {
		die("\n  Sorry, to use Pashua you will have to disable\n".
		    "  safe mode or change the function pashua_run()\n".
		    "  to fit your environment.\n\n");
	}

	// Write configuration string to temporary config file
	$configfile = tempnam('/tmp', 'Pashua_');
	$fp = fopen($configfile, 'w') or user_error("Error trying to open $configfile", E_USER_ERROR);
	fwrite($fp, $conf);
	fclose ($fp);
	
	// Try to figure out the path to pashua
	// First, define the places where to look for Pashua
	$bundlepath = "Pashua.app/Contents/MacOS/Pashua";
	$paths = array(
		dirname(__FILE__).'/Pashua',
		dirname(__FILE__)."/$bundlepath",
		"./$bundlepath",
		"/Applications/$bundlepath",
		"$_SERVER[HOME]/Applications/$bundlepath"
	);

	// Then, look in each of these places
	$path = '';
	foreach ($paths as $searchpath) {
		if (file_exists($searchpath) and
		    is_executable($searchpath)) {
			// Looks like Pashua is in $dir --> exit the loop
			$path = $searchpath;
			break;
		}
	}

	// Raise an error if we didn't find the application
	if (empty($path)) {
		user_error('Unable to locate Pashua', E_USER_ERROR);
	}

	// Call pashua binary with config file as argument and read result
	$cmd = "'$path' $configfile";
	$result = `$cmd`;

	// Remove config file
	unlink($configfile);
	
	// Init result array
	$parsed = array();

	// Parse result
	foreach (explode("\n", $result) as $line) {
		preg_match('/^(\w+)=(.*)$/', $line, $matches);
		if (empty($matches) or empty($matches[1])) {
			continue;
		}
		$parsed[$matches[1]] = $matches[2];
	}

	return $parsed;

} // function pashua_run($conf)




// Define what the dialog should be like
// Take a look at Pashua's Readme file for more info on the syntax
$conf = <<<EOCONF
# Set transparency: 0 is transparent, 1 is opaque
#transparency=0.95

# Set window title
windowtitle = SchoolBus: ATS Conversion Utility

txt_type=text
txt_text=Use this tool to convert your student ATS list to an LDIF file that can be imported into Workgroup Manager on OS X Server.


# Add a filesystem browser
filepath_type = openbrowser
filepath_label = Import File (REQUIRED): 
filepath_width=380
filepath_tooltip= Select your ATS list to convert and choose from the options below.


# Define radiobuttons
passwordtype_type = radiobutton
passwordtype_label = Password Options:
passwordtype_option = Grade as Password
passwordtype_option = Class as Password
passwordtype_option = One Default Password (enter below)
passwordtype_default = One Default Password (enter below)


password_type=textfield
password_label=Enter one default password for all student accounts*
password_default=
password_tooltip=Enter a password for all users (*requires selection of "One default password" above)
password_width=120

# my checkboxes
fixcaps_type=checkbox
fixcaps_label=Fix name capitalization
fixcaps_default=1
fixcaps_tooltip=Turns SMITH JOE to Smith Joe

lowershort_type=checkbox
lowershort_label=Lowercase shortnames 
lowershort_default=1
lowershort_tooltip= Turns SMITHJOE to smithjoe

removechars_type=checkbox
removechars_label=Remove abnormal characters from names
removechars_default=1
removechars_tooltip= Takes out "(", ")", and "." characters from names

# Define radiobuttons
shortnametype_type = radiobutton
shortnametype_label = Before shortname:
shortnametype_option = Put Grade
shortnametype_option = Put Graduation year
shortnametype_option = Put nothing
shortnametype_default = Put nothing

# Define radiobuttons
longnametype_type = radiobutton
longnametype_label = Before longname:
longnametype_option = Put Grade
longnametype_option = Put Graduation year
longnametype_option = Put nothing
longnametype_default = Put nothing

appearance=metal

outputfile_type=savebrowser
outputfile_label=Select a location to save your file (REQUIRED):
#outputfile_default=~/Desktop/importfile.ldif
outputfile_filetype=ldif
outputfile_width=380

# Add a cancel button with default label
cancel_type=cancelbutton

# A default button is added automatically - if you want to
# change the button title, you should uncomment the next
# two lines to override the "built-in" default button
#db_type=defaultbutton
#db_label=Click here to return the values

EOCONF;

# Pass the configuration string to the Pashua module
$result = pashua_run($conf);

//print "	 Pashua returned the following array:\n";
//print_r($result);

if ($result[cancel] == 1)     die("cancelled\n");

$fixcaps = $result[fixcaps];
$removechars = $result[removechars];
$grlong = $result[grlong];
$grshort = $result[grshort];
$lowershort = $result[lowershort];


/*if (count($argv) == 1) {
    die($argv[0] . ": try '" . $argv[0] . " --help' or '" . $argv[0] . " --manual' for more information\n");
}*/

//var_dump($argv);

$output_buffer;
if (!($file = file($result[filepath]))){
    echo CDokmsgbox("Error","File missing","Please choose an ATS file to convert.",true)."\n";
    $result = pashua_run($conf);
}

$students = array();

//look for student number line
$totalnumstring = "TOTAL NUMBER OF STUDENTS = ";
$schoolnamestring = "CROSS REFERENCE LIST FOR ";
foreach ($file as $line){
    if (($val = stristr($line, $schoolnamestring)) && !$nomore) {
        //echo substr(substr($val, 0, strlen($val) - 11), 25);
        $nomore = 1;
    }
    if (stristr($line, $totalnumstring)) {         
        $student_count = trim(str_replace($totalnumstring, "", $line));
        //echo "student count = " . $student_count . "\n";
    }
    
}


$header_string = "0x0A 0x5C 0x3A 0x3B dsRecTypeStandard:Users 36 dsAttrTypeStandard:RecordName dsAttrTypeStandard:AuthMethod dsAttrTypeStandard:Password dsAttrTypeStandard:UniqueID dsAttrTypeStandard:PrimaryGroupID  dsAttrTypeStandard:Comment dsAttrTypeStandard:Expire dsAttrTypeStandard:Change dsAttrTypeStandard:RealName dsAttrTypeStandard:NFSHomeDirectory dsAttrTypeStandard:UserShell dsAttrTypeStandard:PrintServiceInfoXML dsAttrTypeStandard:HomeDirectory dsAttrTypeStandard:HomeDirectoryQuota dsAttrTypeStandard:MailAttribute dsAttrTypeStandard:Keywords dsAttrTypeStandard:FirstName dsAttrTypeStandard:LastName dsAttrTypeStandard:JobTitle dsAttrTypeStandard:OrganizationName dsAttrTypeStandard:Department dsAttrTypeStandard:Building dsAttrTypeStandard:PhoneNumber dsAttrTypeStandard:MobileNumber dsAttrTypeStandard:FaxNumber dsAttrTypeStandard:EMailAddress dsAttrTypeStandard:Street dsAttrTypeStandard:City dsAttrTypeStandard:State dsAttrTypeStandard:Country dsAttrTypeStandard:PostalCode dsAttrTypeStandard:Picture dsAttrTypeStandard:SMBHome dsAttrTypeStandard:SMBHomeDrive dsAttrTypeStandard:SMBProfilePath dsAttrTypeStandard:SMBScriptPath\n";


//returns 1 if line is ok -doesn't include the ignore strings
function check_strings ($line){
    $ignore_strings = array("==========", "ATS - NEW YORK CITY PUBLIC SCHOOLS", "CROSS REFERENCE LIST", "NAME            NUMBER   CLS GRD GR ROOM ST SEX   PHONE #        DOB", "*****", $totalnumstring);
    foreach ($ignore_strings as $ignore_string){
        if (stristr($line, $ignore_string)) return 0;
    }
    return 1;
}

function fix_grade ($grade){
    $listed_grades = array("0K", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12");
    for($i=0; $i< count($listed_grades); $i++){
        if ($grade == "PK") return "PK";
        if ($grade == "0K") return "K";
        if ($grade == $listed_grades[$i]) return $i;
    }
}

function create_shortname ($name){
    global $removechars;
    global $lowershort;
    if ($removechars) $ignore_chars = array("(", ")", " ", "."); 
    else $ignore_chars = array(" "); 
    foreach ($ignore_chars as $ignore_char){
        $name = str_replace ($ignore_char, "", $name);
    }
    if ($lowershort == 1) {
        return strtolower($name);
    } else {
        return strtoupper($name);
    }
}

// progressbar
//$myPBar = CDprogressbar("CocoaDialog : progressbar","progress bar");
$j=0;
$file_line_count = count($file);
for ($i=10; $i < $file_line_count; $i++){
    if ((check_strings($file[$i])) & (strlen($file[$i]) > 4)) {
         if ($result[fixcaps] == 1) $name = ucwords(strtolower(trim(substr($file[$i], 0, strlen($file[$i]) - 58))));
        else $name = strtoupper(trim(substr($file[$i], 0, strlen($file[$i]) - 58)));
        $grade = trim(substr(substr($file[$i], 0, strlen($file[$i]) - 35), -5, 3));
        //$grade2 = trim(substr(substr($file[$i], 0, strlen($file[$i]) - 35), -5));
        //$grade = substr(trim(substr(substr($file[$i], 0, strlen($file[$i]) - 35), -5)), 3);


//echo CDokmsgbox("Error","Grade","$name 1: $grade 2: $grade2\n",true);

        $class = trim(substr(substr($file[$i], 0, strlen($file[$i]) - 44), -5));
        $new_array = array($name, $grade, $class);
        $students[$j] = $new_array;
            
        //grade stuff
        if ($i == 10){
            $lowest_grade = $grade;
            $highest_grade = $grade;
        }
        if ($grade == "0K") $grade = 0;
        if ($grade == "PK") $grade = -1;
        if ($grade > $highest_grade) $highest_grade = $grade;
        if ($grade < $lowest_grade) $lowest_grade = $grade;
        $j++;
        $percent_done = $i / $file_line_count / 2;
        //CDbarvalue($myPBar, $percent_done ,"Calculation progress: ".$percent_done."%");
        //echo "percent done: $percent_done %\n";

    }
}

$file_date = strtotime(substr(stristr($file[4], "DATE: "), 5));
//if month is august or later, school year is next year
if (date("n",$file_date) > 7) $school_year = date("Y",$file_date) + 1;
else $school_year = date("Y",$file_date);

//$school_year_text = date("F j, Y",strtotime(substr(stristr($file[4], "DATE: "), 5)));

function graduationYear($oldest_grade, $current_year, $input_grade){
    return (($oldest_grade - $input_grade) + $current_year);
}

/*if (stristr($result[shortnametype], "Put Graduation year")){
    echo CDokmsgbox("Error","Grad Year","Must figure this out. School Year: $school_year. " . ($lowest_grade + 1) . "st graders will graduate in " . graduationYear($highest_grade, $school_year, ($lowest_grade + 1))  . ".  HG: $highest_grade LG: $lowest_grade SY: $school_year\n",true);
    exit();
}*/



$output_buffer = $output_buffer . $header_string;
foreach ($students as $student){

    if (stristr($result[passwordtype], "Grade as Password")){
        $password = fix_grade($student[1]);
    } else if (stristr($result[passwordtype], "Class as Password")){
        $password = $student[2];
    } else if (strlen($result[password])) {
        $password = $result[password]; 
    } else $password = "";


    if (stristr($result[shortnametype], "Put Grade")){
        $output_buffer = $output_buffer . fix_grade($student[1]);
    } else if (stristr($result[shortnametype], "Put Graduation year")){
        $output_buffer = $output_buffer . graduationYear($highest_grade, $school_year, (fix_grade($student[1])));
    } 
    
    //if ($result[grshort]) $output_buffer = $output_buffer . fix_grade($student[1]);


    $output_buffer = $output_buffer . create_shortname($student[0]) . ":dsAuthMethodStandard\:dsAuthClearText:" . $password . "::20::::";
    
    if (stristr($result[longnametype], "Put Grade")){
        $output_buffer = $output_buffer . fix_grade($student[1]) . " ";
    } else if (stristr($result[longnametype], "Put Graduation year")){
        $output_buffer = $output_buffer . graduationYear($highest_grade, $school_year, (fix_grade($student[1]))) . " ";
    } 
    $output_buffer = $output_buffer . $student[0] . "::None:::::::::::::::::::::::::\n"; 
    unset($password);
}
//fclose($myPBar);


$filename = $result[outputfile];

// Let's make sure the file exists and is writable first.
if (!file_exists($filename)) {

   // In our example we're opening $filename in append mode.
   // The file pointer is at the bottom of the file hence 
   // that's where $somecontent will go when we fwrite() it.
   if (!$handle = fopen($filename, 'a')) {
        echo CDokmsgbox("Error","File error","Cannot create the file$filename.",true)."\n";

         echo "Cannot open file ($filename)";
         exit;
   }

   // Write $somecontent to our opened file.
   if (fwrite($handle, $output_buffer) === FALSE) {
        echo CDokmsgbox("Error","File error","Cannot write to file$filename.",true)."\n";

       //echo "Cannot write to file ($filename)";
       exit;
   }
   
   //echo "Success, wrote ($output_buffer) to file ($filename)";
        echo CDokmsgbox("SchoolBus","Conversion Complete","The file $filename is now ready for use with Workgroup Manager.",true)."\n";
   fclose($handle);

} else {
    echo CDokmsgbox("Error","File error","The file $filename already exists and cannot be created.",true)."\n";
   //echo "The file $filename already exists";
}

?> 
